from jili.trade.constants import adapter_subjects
from jili.core import moheengine as mh
import threading
import os
from jili.core.printlog import print
"""as
1.adapter 统一的 API层；给业务进程调用；最终是策略SS调用   SS进程<——>Trade Adapter进程的关键通信层
2.SS内部   pos——>tarde——>adapterapi
"""
pid = str(os.getpid())
class adpaterapi():
    def __init__(self,brokerid,investid,adaptertype="ctp"):
        self.islogin = False
        if adaptertype == "sim":
            self.islogin = True
        self.adaptertype=adaptertype
        self.subject_up = adapter_subjects[adaptertype]["up"]
        self.subject_down = adapter_subjects[adaptertype]["dwon"]
        self.investorid = investid
        self.brokerid = brokerid
        self.__RequestID = 0
        self.__qry_sync_rst = {}
        self.__useroncall={}
        self.__cmdoncall={}
        self.__isposfirst=True
        self.__isposdetailfirst=True
        self.TIMEOUT = 30
        mh.subscribe(self.__onadapter, self.__subject_down, investid)
    def __IncRequestID(self):
        """ 自增并返回请求ID """
        self.__RequestID += 1
        return pid+"_"+str(self.__RequestID)
    def setoncall(self,cmd,oncall):
        if cmd not in self.__cmdoncall.keys():
            self.__cmdoncall[cmd]=[oncall]
        else:
            self.__cmdoncall[cmd].append(oncall)
    def __onadapter(self, msg):
        """
        m={}
        m["0"]="acknotify"  #msgtype
        m["1"]=str(msg["s"]["pid"])  #subject
        m["2"]={cmd:,data:}   #data必有 cmd,data  可有  requstid，rsqid,islast,
        t=msg["s"]
        t["isreply"]=False
        m["s"]=t
        m["e"]=getsource()
        call(data)
        data={"RequestID","RspInfo","data",}
        """
        # print("__onadapter",msg)
        data = msg["2"]
        cmd=data["cmd"]
        if cmd in self.__cmdoncall.keys():
            if cmd=="onpos":
                islast=data["IsLast"]
                if self.__isposfirst:
                    self.__isposfirst=False
                    for call in self.__cmdoncall(cmd):
                        call(data["data"],0)
                else:
                    if not islast:
                        for call in self.__cmdoncall(cmd):
                            call(data["data"], 1)
                    else:
                        for call in self.__cmdoncall(cmd):
                            call(data["data"], 2)
                if islast:
                    self.__isposfirst = True
            elif cmd=="onposdetail":
                islast = data["IsLast"]
                if self.__isposdetailfirst:
                    self.__isposdetailfirst = False
                    for call in self.__cmdoncall(cmd):
                        call(data["data"], 0)
                else:
                    if not islast:
                        for call in self.__cmdoncall(cmd):
                            call(data["data"], 1)
                    else:
                        for call in self.__cmdoncall(cmd):
                            call(data["data"], 2)
                if islast:
                    self.__isposdetailfirst = True
            else:
                for call in self.__cmdoncall(cmd):
                    if "data" in data.keys():
                        call(data["data"])
                    else:
                        call(data)
        if "RequstID" in data.keys():#查询
            requstid = data["RequestID"]
            if requstid in self.__useroncall.keys():
                self.__useroncall[requstid](data)
            if "IsLast" in data.keys():
                if data["IsLast"]:
                    del self.__useroncall[requstid]
            else:
                del self.__useroncall[requstid]
            #同步回调处理
            if self.__qry_sync_rst:
                if data["RequestID"] == self.__qry_sync_rst["RequestID"]:
                    if "data" in data.keys():
                        t=[data["data"]]
                    else:
                        t=[data]
                    if "IsLast" in data.keys():
                        if not data["IsLast"]:
                            t.append(data["data"])
                        else:
                            self.__qry_sync_rst.update(data["RspInfo"])
                            self.__qry_sync_rst["data"] = t
                            self.__qry_sync_rst["event"].set()
                    else:
                        self.__qry_sync_rst.update(data["RspInfo"])
                        self.__qry_sync_rst["data"] = t
                        self.__qry_sync_rst["event"].set()

    def login(self, password):
        msg = dict(cmd="login", brokerid=self.brokerid, investorid=self.investorid, password=password,
                   RequestID=self.__IncRequestID(), PID=pid)
        self.__qry_sync_rst["event"] = threading.Event()
        self.__qry_sync_rst["RequestID"] = msg["RequestID"]
        self.__qry_sync_rst['event'].clear()
        rst = mh.safesend_sync(self.__subject_up, self.investorid, msg)
        code=0
        if rst["errcode"] == 0:
            if self.__qry_sync_rst['event'].wait(self.TIMEOUT):
                if self.__qry_sync_rst['ErrorID'] == 0:
                    self.islogin = True
                else:
                    self.islogin =False
                    code=self.__qry_sync_rst['ErrorID']
        else:
            code=rst["errcode"]
        return self.islogin,code
    def logout(self):
        msg = dict(cmd="logout", InvestorID=self.investorid, UserID=self.investorid,
                   RequestID=self.__IncRequestID(),
                   PID=pid)
        self.__qry_sync_rst["event"] = threading.Event()
        self.__qry_sync_rst["RequestID"] = msg["RequestID"]
        self.__qry_sync_rst['event'].clear()
        rst = mh.safesend_sync(self.__subject_up, self.investorid, msg)
        if rst["errcode"] == 0:
            if self.__qry_sync_rst['event'].wait(self.TIMEOUT):
                if self.__qry_sync_rst['ErrorID'] == 0:
                    return True
                else:
                    return False
            else:
                return False
        else:
            return False
    def call(self,req, issync=True, oncall=""):
        req["InvestorID"] = self.investorid
        req["RequestID"] = self.__IncRequestID()
        ret = {}
        a = False
        if not issync and oncall != "":
            self.__useroncall[req["RequestID"]] = oncall
        if issync:
            self.__qry_sync_rst["event"] = threading.Event()
            self.__qry_sync_rst["RequestID"] = req["RequestID"]
            self.__qry_sync_rst['event'].clear()
        rst = mh.safesend_sync(self.__subject_up, self.investorid, req)
        if issync:
            if rst["errcode"] == 0:
                if self.__qry_sync_rst['event'].wait(self.TIMEOUT):
                    # print(self.__qry_sync_rst)
                    if self.__qry_sync_rst['ErrorID'] == 0:
                        a = True
                        ret = self.__qry_sync_rst['data']
        else:
            if rst["errcode"] == 0:
                a = True
        return req["RequestID"], a, ret
    def qry_safe(self,req, issync=True, oncall=""):
        req["InvestorID"] = self.investorid
        req["RequestID"] = self.__IncRequestID()
        rsq={"cmd":"qry_safe","data":req}
        ret = {}
        a = False
        if oncall != "":
            self.__useroncall[req["RequestID"]] = oncall
        if issync:
            self.__qry_sync_rst["event"] = threading.Event()
            self.__qry_sync_rst["RequestID"] = req["RequestID"]
            self.__qry_sync_rst['event'].clear()
        rst = mh.safesend_sync(self.__subject_up, self.investorid, rsq)
        if issync:
            if rst["errcode"] == 0:
                if self.__qry_sync_rst['event'].wait(self.TIMEOUT):
                    # print(self.__qry_sync_rst)
                    if self.__qry_sync_rst['ErrorID'] == 0:
                        a = True
                        ret = self.__qry_sync_rst['data']
        else:
            if rst["errcode"] == 0:
                a = True
        return req["RequestID"], a, ret